import { NextRequest } from 'next/server';
import { withMiddleware } from '@/lib/middleware/entry';
import { prisma } from '@/lib/prisma';
import { authenticateRequest } from '@/utils/auth';
import { errorResponse, successResponse } from '@/lib/response';
import { uploadFile as uploadToStorage } from '@/lib/storage';
import { randomUUID } from 'crypto';

function resolveIconUrl(html: string, siteUrl: string): string {
  try {
    const origin = new URL(siteUrl).origin;
    // 解析常见的 icon 链接
    const linkIconRegex = /<link[^>]+rel=["']?(?:shortcut\s+icon|icon|apple-touch-icon(?:-precomposed)?)["']?[^>]*href=["']?([^"'>\s]+)/ig;
    const candidates: string[] = [];
    let match: RegExpExecArray | null;
    while ((match = linkIconRegex.exec(html)) !== null) {
      const href = match[1];
      try {
        candidates.push(new URL(href, origin).toString());
      } catch {}
    }
    if (candidates.length > 0) return candidates[0];

    // 解析 og:image 作为兜底
    const ogImageRegex = /<meta[^>]+property=["']?og:image["']?[^>]*content=["']?([^"'>\s]+)/i;
    const ogMatch = ogImageRegex.exec(html);
    if (ogMatch) {
      try {
        return new URL(ogMatch[1], origin).toString();
      } catch {}
    }

    // 最后兜底 favicon.ico
    return new URL('/favicon.ico', origin).toString();
  } catch {
    // siteUrl 解析失败直接兜底
    return siteUrl.endsWith('/favicon.ico') ? siteUrl : `${siteUrl}/favicon.ico`;
  }
}

function guessExt(contentType: string | null, iconUrl: string): string {
  const fromType = (type: string) => {
    if (type.includes('png')) return 'png';
    if (type.includes('jpeg')) return 'jpg';
    if (type.includes('jpg')) return 'jpg';
    if (type.includes('gif')) return 'gif';
    if (type.includes('webp')) return 'webp';
    if (type.includes('svg')) return 'svg';
    if (type.includes('x-icon') || type.includes('vnd.microsoft.icon')) return 'ico';
    return '';
  };
  const byType = contentType ? fromType(contentType) : '';
  if (byType) return byType;
  try {
    const url = new URL(iconUrl);
    const ext = url.pathname.split('.').pop()?.toLowerCase();
    if (ext) return ext;
  } catch {}
  return 'ico';
}

async function handler(req: NextRequest) {
  const auth = await authenticateRequest(req);
  if (!auth.success || !auth.user) {
    return errorResponse(auth.error || '未认证', 401);
  }

  const { contentId } = (await req.json().catch(() => ({ contentId: '' }))) as { contentId: string };
  if (!contentId) return errorResponse('缺少内容ID', 400);

  const content = await prisma.content.findUnique({ where: { id: contentId } });
  if (!content) return errorResponse('内容不存在', 404);
  const siteUrl = content.url;
  if (!siteUrl || !siteUrl.startsWith('http')) {
    return errorResponse('内容未配置合法站点地址', 400);
  }

  // 获取页面HTML并解析icon地址
  let iconUrl = '';
  try {
    const res = await fetch(siteUrl, { redirect: 'follow' });
    const html = await res.text();
    iconUrl = resolveIconUrl(html, siteUrl);
  } catch (e) {
    // 兜底直接尝试 favicon.ico
    try {
      iconUrl = new URL('/favicon.ico', siteUrl).toString();
    } catch {
      return errorResponse('无法解析图标地址', 500);
    }
  }

  // 下载图标
  try {
    let iconRes = await fetch(iconUrl, { redirect: 'follow' });
    if (!iconRes.ok) {
      const fallbackUrl = new URL('/favicon.ico', siteUrl).toString();
      iconRes = await fetch(fallbackUrl, { redirect: 'follow' });
      if (!iconRes.ok) {
        return errorResponse(`抓取图标失败: ${iconRes.status}`, 500);
      }
      iconUrl = fallbackUrl;
    }

    const bytes = await iconRes.arrayBuffer();
    const buffer = Buffer.from(bytes);
    const ext = guessExt(iconRes.headers.get('content-type'), iconUrl);
    const safeName = `icon_${randomUUID()}.${ext}`;

    const stored = await uploadToStorage(buffer, safeName, 'icons/');

    const record = await prisma.file.create({
      data: {
        userId: auth.user.id,
        provider: 'minio',
        bucket: process.env.MINIO_BUCKET_NAME || 'kason-world',
        path: stored.path,
        url: stored.url,
        mimeType: stored.mimeType,
        size: stored.size,
        visibility: 'public',
        category: 'image',
        source: 'icon-sync',
        status: 'active',
      }
    });

    await prisma.content.update({
      where: { id: contentId },
      data: { coverId: record.id }
    });

    return successResponse({ fileId: record.id, url: record.url, path: record.path, iconSource: iconUrl });
  } catch (e: any) {
    console.error('同步图标错误:', e);
    return errorResponse(`同步图标失败: ${e?.message || e}`, 500);
  }
}

export const POST = withMiddleware(handler);